#include "scenario_test.h"

#include <bn_core.h>
#include <bn_keypad.h>
#include <bn_log.h>

#include "tools.h"

namespace
{
    static int nyra_anim_counter{0};
    static bool nyra_anim_switch{true};
    static int anim_switch_value{};
    static bn::random randomizer{};
}

void scenario_test::nyraAnimationUpdate()
{
    if (nyra_anim_counter == 0)
    {
        nyraAnimation = bn::create_sprite_animate_action_forever(
                    nyraSprite.getSpritePtr(),
                    nyra_anim_switch ? 10 : 4,
                    bn::sprite_items::nyra32_playing.tiles_item(),
                    nyra_anim_switch ? 0 : 2,
                    nyra_anim_switch ? 1 : 3);

        nyra_anim_switch ^= 1;

        anim_switch_value = randomizer.get_int(
                    nyra_anim_switch ? 60 : 20,
                    nyra_anim_switch ? 500 : 150);
    }

    if (++nyra_anim_counter >= anim_switch_value)
    {
        nyra_anim_counter = 0;
    }

    nyraAnimation->update();
}

bool scenario_test::playerMovementUpdate()
{
    for (const auto& [keyName, dirName] : keyDirBindings)
    {
        if (bn::keypad::pressed(keyName))
        {
            playerSprite.setAsMovable(true);
            playerSprite.setDirection(keyDirBindings[keyName]);
            playerSprite.setMoveAnimation();
            return true;
        }

        if (bn::keypad::held(keyName))
        {
            playerSprite.update();
            return true;
        }

        if (bn::keypad::released(keyName))
        {
            playerSprite.setAsMovable(false);
            playerSprite.setStaticFrame();
            return false;
        }
    }

    return false;
}

void scenario_test::zOrderUpdate()
{
    for (int index{}; index < objects.size(); ++index)
    {
        for (int next{}; next < objects.size(); ++next)
        {
            if (index == next)
            {
                continue;
            }

            if (checker::areObjectsOverlapping(objects[index]->getCollisionRect(), objects[next]->getCollisionRect(), objects[index]->getSpriteHeight(), objects[next]->getSpriteHeight()))
            {
                if (checker::isObjectAInFrontOfObjectB(objects[index]->getCollisionRect(), objects[next]->getCollisionRect(), objects[index]->getSpriteHeight(), objects[next]->getSpriteHeight()))
                {
                    objects[index]->setZOrder(objects[next]->getZOrder()-1);
                }
            }
        }
    }
}

scenario_test::scenario_test()
    : nyraSprite{-8,0,bn::sprite_items::nyra32_playing,8,8,32}
    , playerSprite{0,0,bn::sprite_items::main32,8,8,10,32}
    , classroomBg{bn::regular_bg_items::iso_classroom.create_bg(0,-32)}
{
    scenarioInit();

    keyDirBindings.insert({bn::keypad::key_type::UP, movableSprite::Direction::Up});
    keyDirBindings.insert({bn::keypad::key_type::LEFT, movableSprite::Direction::Left});
    keyDirBindings.insert({bn::keypad::key_type::DOWN, movableSprite::Direction::Down});
    keyDirBindings.insert({bn::keypad::key_type::RIGHT, movableSprite::Direction::Right});
}

void scenario_test::scenarioInit()
{
    objects.push_back(new staticSprite{12,40,bn::sprite_items::toru32_desk,16,16,32});
    objects.push_back(new staticSprite{30,40,bn::sprite_items::desknchair32,16,16,32});
    objects.push_back(new staticSprite{60,-20,bn::sprite_items::yuji32_idle,16,16,48});
    objects.push_back(&nyraSprite);
    objects.push_back(&playerSprite);

    for (auto& object : objects)
    {
        object->draw();
    }
}

void scenario_test::scenarioUpdate()
{
    nyraAnimationUpdate();

    if (playerMovementUpdate())
    {
        zOrderUpdate();
    }

    for (auto& object : objects)
    {
        object->draw();
    }
}
